<template>
    <el-upload
        ref="uploadRef"
        :action="uploadUrl"
        :disabled="loading"
        list-type="picture-card"
        :accept="props.acceptTypes"
        :class="{ hide: hideUpload }"
        :headers="headers"
        :on-success="successHandler"
        :on-error="errorHandler"
        :on-progress="progressHandler"
        :before-upload="beforeUploadHandler">
        <el-icon>
            <Plus />
        </el-icon>
        <template #file="{ file }">
            <div v-loading="loading" class="preview-company-logo">
                <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
                <span class="el-upload-list__item-actions">
                    <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                        <el-icon><zoom-in /></el-icon>
                    </span>
                    <span class="el-upload-list__item-delete" @click="handleRemove(file)">
                        <el-icon><Delete /></el-icon>
                    </span>
                </span>
            </div>
        </template>
        <template #tip>
            <div class="upload-tip" v-if="props.tipContent">
                <el-icon color="#FF6B00" :size="16" class="tip-icon">
                    <InfoFilled />
                </el-icon>
                <span> {{ props.tipContent }} </span>
            </div>
        </template>
    </el-upload>
    <el-dialog top="8vh" v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" class="preview-img" />
    </el-dialog>
</template>

<script setup>
import { ref, reactive, inject } from 'vue';
const emit = defineEmits(['imgStateChange']);
import storage from '@/commons/storage.js';
const bus = inject('bus');

const props = defineProps({
    // tip
    tipContent: { type: String, default: '' },
    // 图片类型
    acceptTypes: { type: String, default: '.jpg,.png,.jpeg' },
    // 图片大小
    maxSize: { type: Number, default: 10 },
    // 其他校验条件
    validator: { type: Function, default: () => {} }
});
const headers = reactive({
    'ZW-PLATFORM-TOKEN': storage.get('ZW-TOKEN')
});
const uploadRef = ref(null);
const dialogImageUrl = ref('');
const dialogVisible = ref(false);
const disabled = ref(false);
let imgUrl = ref('');
let tempUrl = '';
if (import.meta.env.VITE_RUNTIME_ENV === 'local') {
    tempUrl = '/zwapi/common/file/upload';
} else {
    tempUrl = import.meta.env.VITE_BASE_API_URL + '/common/file/upload';
}
let uploadUrl = ref(tempUrl);
let loading = ref(false);
let hideUpload = ref(false);

const beforeUploadHandler = file => {
    const acceptTypeArr = props.acceptTypes.split(',').map(x => {
        return 'image/' + x.replace('.', '');
    });
    // 考虑到服务端有文件类型和文件大小限制，所以这俩为必须校验
    if (!acceptTypeArr.includes(file.type)) {
        emitHandler({ msg: '上传图片格式不正确！' });
        return false;
    } else if (file.size / 1024 / 1024 > props.maxSize) {
        emitHandler({ msg: `图片大小限制${props.maxSize}M以内！` });
        return false;
    }
    return props.validator(file);
};

const handleRemove = () => {
    uploadRef.value.clearFiles();
    hideUpload.value = false;
    imgUrl.value = '';
    emitHandler({ imgUrl });
};

const handlePictureCardPreview = file => {
    dialogImageUrl.value = file.url;
    dialogVisible.value = true;
};

const successHandler = res => {
    loading.value = false;
    if (res.code === 0) {
        imgUrl.value = res.data.uri;
        emitHandler({ imgUrl });
    } else {
        emitHandler({ msg: res.msg || '图片上传失败，请刷新重试！' });
    }
};

const errorHandler = res => {
    loading.value = false;
    hideUpload.value = false;
    emitHandler({ msg: res.msg || '图片上传失败，请刷新重试' });
};

const progressHandler = () => {
    loading.value = true;
    hideUpload.value = true;
};

const emitHandler = ({ imgUrl, msg }) => {
    emit('imgStateChange', { imgUrl, msg });
};
</script>

<style lang="scss" scoped>
.preview-img {
    width: 100%;
    border-style: none;
}
.upload-tip {
    font-size: 12px;
    line-height: 40px;
    width: 400px;
    word-break: break-all;
    color: #909399;
    .tip-icon {
        vertical-align: middle;
        margin-bottom: 4px;
    }
}
.hide {
    :deep(.el-upload--picture-card) {
        display: none;
    }
}
</style>
